home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.5 Applications 2004 May / SGI IRIX 6.5 Applications 2004 May.iso / dist / java3d.idb / usr / demos / java / j3d / programs / examples / GearTest / Gear.java.z / Gear.java
Encoding:
Java Source  |  2003-08-08  |  13.6 KB  |  393 lines

  1. /*
  2.  *    @(#)Gear.java 1.11 02/04/01 15:03:17
  3.  *
  4.  * Copyright (c) 1996-2002 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  *
  10.  * - Redistributions of source code must retain the above copyright
  11.  *   notice, this list of conditions and the following disclaimer.
  12.  *
  13.  * - Redistribution in binary form must reproduce the above copyright
  14.  *   notice, this list of conditions and the following disclaimer in
  15.  *   the documentation and/or other materials provided with the
  16.  *   distribution.
  17.  *
  18.  * Neither the name of Sun Microsystems, Inc. or the names of
  19.  * contributors may be used to endorse or promote products derived
  20.  * from this software without specific prior written permission.
  21.  *
  22.  * This software is provided "AS IS," without a warranty of any
  23.  * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
  24.  * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
  25.  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
  26.  * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
  27.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  28.  * DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
  29.  * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
  30.  * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
  31.  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
  32.  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
  33.  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  34.  *
  35.  * You acknowledge that Software is not designed,licensed or intended
  36.  * for use in the design, construction, operation or maintenance of
  37.  * any nuclear facility.
  38.  */
  39.  
  40. import java.lang.Math.*;
  41. import javax.media.j3d.*;
  42. import javax.vecmath.*;
  43.  
  44. public class Gear extends javax.media.j3d.TransformGroup {
  45.     
  46.     // Specifiers determining whether to generate outward facing normals or
  47.     // inward facing normals.
  48.     static final int OutwardNormals = 1;
  49.     static final int InwardNormals = -1;
  50.  
  51.     // The number of teeth in the gear
  52.     int toothCount;
  53.  
  54.     // Gear start differential angle. All gears are constructed with the
  55.     // center of a tooth at Z-axis angle = 0.
  56.     double gearStartAngle;
  57.     // The Z-rotation angle to place the tooth center at theta = 0
  58.     float toothTopCenterAngle;
  59.     // The Z-rotation angle to place the valley center at theta = 0
  60.     float valleyCenterAngle;
  61.     // The angle about Z subtended by one tooth and its associated valley
  62.     float circularPitchAngle;
  63.     
  64.     // Increment angles
  65.     float toothValleyAngleIncrement;
  66.  
  67.     // Front and rear facing normals for the gear's body
  68.     final Vector3f frontNormal = new Vector3f(0.0f, 0.0f, -1.0f);
  69.     final Vector3f rearNormal = new Vector3f(0.0f, 0.0f, 1.0f);
  70.  
  71.  
  72.     Gear(int toothCount) {
  73.     this.toothCount = toothCount;
  74.     }
  75.  
  76.     void addBodyDisks(float shaftRadius, float bodyOuterRadius,
  77.               float thickness, Appearance look) {
  78.     int gearBodySegmentVertexCount;        // #(segments) per tooth-unit
  79.     int gearBodyTotalVertexCount;        // #(vertices) in a gear face
  80.     int gearBodyStripCount[] = new int[1];    // per strip (1) vertex count
  81.  
  82.     // A ray from the gear center, used in normal calculations
  83.     float xDirection, yDirection;
  84.  
  85.     // The x and y coordinates at each point of a facet and at each
  86.     // point on the gear: at the shaft, the root of the teeth, and
  87.     // the outer point of the teeth
  88.     float xRoot0, yRoot0, xShaft0, yShaft0;
  89.     float xRoot3, yRoot3, xShaft3, yShaft3;
  90.     float xRoot4, yRoot4, xShaft4, yShaft4;
  91.  
  92.     // Temporary variables for storing coordinates and vectors 
  93.     Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f);
  94.  
  95.     // Gear start differential angle. All gears are constructed with the
  96.     // center of a tooth at Z-axis angle = 0.
  97.     double gearStartAngle = -1.0 * toothTopCenterAngle;
  98.  
  99.     // Temporaries that store start angle for each portion of tooth facet
  100.     double toothStartAngle, toothTopStartAngle,
  101.         toothDeclineStartAngle, toothValleyStartAngle,
  102.         nextToothStartAngle;
  103.  
  104.     Shape3D newShape;
  105.     int index;
  106.  
  107.     // The z coordinates for the body disks
  108.     final float frontZ = -0.5f * thickness;
  109.     final float rearZ = 0.5f * thickness;
  110.  
  111.     /* Construct the gear's front body (front facing torus disk)
  112.      *                   __2__
  113.      *                -    |    -  4
  114.      *             -       /|     /-
  115.      *           /        / |    /| \
  116.      *          0\       /  |   / /  >
  117.      *            \     /   |  /  |   >
  118.      *             \   /    | /  /     |
  119.      *              \ / ____|/   |      >
  120.      *               \--    --__/       | 
  121.      *                1     3   5
  122.      *
  123.      */
  124.     gearBodySegmentVertexCount = 4;
  125.     gearBodyTotalVertexCount = 2 + gearBodySegmentVertexCount * toothCount;
  126.     gearBodyStripCount[0] = gearBodyTotalVertexCount;
  127.  
  128.     TriangleStripArray frontGearBody
  129.         = new TriangleStripArray(gearBodyTotalVertexCount,
  130.                      GeometryArray.COORDINATES
  131.                      | GeometryArray.NORMALS,
  132.                      gearBodyStripCount);
  133.  
  134.     xDirection = (float)Math.cos(gearStartAngle);
  135.     yDirection = (float)Math.sin(gearStartAngle);
  136.     xShaft0 = shaftRadius * xDirection;
  137.     yShaft0 = shaftRadius * yDirection;
  138.     xRoot0 = bodyOuterRadius * xDirection;
  139.     yRoot0 = bodyOuterRadius * yDirection;
  140.  
  141.     coordinate.set(xRoot0, yRoot0, frontZ);
  142.     frontGearBody.setCoordinate(0, coordinate);
  143.     frontGearBody.setNormal(0, frontNormal);
  144.  
  145.     coordinate.set(xShaft0, yShaft0, frontZ);
  146.     frontGearBody.setCoordinate(1, coordinate);
  147.     frontGearBody.setNormal(1, frontNormal);
  148.  
  149.     for(int count = 0; count < toothCount; count++) {
  150.         index = 2 + count * 4;
  151.         toothStartAngle
  152.         = gearStartAngle + circularPitchAngle * (double)count;
  153.         toothValleyStartAngle
  154.         = toothStartAngle + toothValleyAngleIncrement;
  155.         nextToothStartAngle = toothStartAngle + circularPitchAngle;
  156.  
  157.         xDirection = (float)Math.cos(toothValleyStartAngle);
  158.         yDirection = (float)Math.sin(toothValleyStartAngle);
  159.         xShaft3 = shaftRadius * xDirection;
  160.         yShaft3 = shaftRadius * yDirection;
  161.         xRoot3 = bodyOuterRadius * xDirection;
  162.         yRoot3 = bodyOuterRadius * yDirection;
  163.  
  164.         xDirection = (float)Math.cos(nextToothStartAngle);
  165.         yDirection = (float)Math.sin(nextToothStartAngle);
  166.         xShaft4 = shaftRadius * xDirection;
  167.         yShaft4 = shaftRadius * yDirection;
  168.         xRoot4 = bodyOuterRadius * xDirection;
  169.         yRoot4 = bodyOuterRadius * yDirection;
  170.  
  171.         coordinate.set(xRoot3, yRoot3, frontZ);
  172.         frontGearBody.setCoordinate(index, coordinate);
  173.         frontGearBody.setNormal(index, frontNormal);
  174.  
  175.         coordinate.set(xShaft3, yShaft3, frontZ);
  176.         frontGearBody.setCoordinate(index + 1, coordinate);
  177.         frontGearBody.setNormal(index + 1, frontNormal);
  178.  
  179.         coordinate.set(xRoot4, yRoot4, frontZ);
  180.         frontGearBody.setCoordinate(index + 2, coordinate);
  181.         frontGearBody.setNormal(index + 2, frontNormal);
  182.  
  183.         coordinate.set(xShaft4, yShaft4, frontZ);
  184.         frontGearBody.setCoordinate(index + 3, coordinate);
  185.         frontGearBody.setNormal(index + 3, frontNormal);
  186.     }
  187.     newShape = new Shape3D(frontGearBody, look);
  188.     this.addChild(newShape);
  189.  
  190.     // Construct the gear's rear body (rear facing torus disc)
  191.     TriangleStripArray rearGearBody
  192.         = new TriangleStripArray(gearBodyTotalVertexCount,
  193.                      GeometryArray.COORDINATES
  194.                      | GeometryArray.NORMALS,
  195.                      gearBodyStripCount);
  196.     xDirection = (float)Math.cos(gearStartAngle);
  197.     yDirection = (float)Math.sin(gearStartAngle);
  198.     xShaft0 = shaftRadius * xDirection;
  199.     yShaft0 = shaftRadius * yDirection;
  200.     xRoot0 = bodyOuterRadius * xDirection;
  201.     yRoot0 = bodyOuterRadius * yDirection;
  202.  
  203.     coordinate.set(xShaft0, yShaft0, rearZ);
  204.     rearGearBody.setCoordinate(0, coordinate);
  205.     rearGearBody.setNormal(0, rearNormal);
  206.  
  207.     coordinate.set(xRoot0, yRoot0, rearZ);
  208.     rearGearBody.setCoordinate(1, coordinate);
  209.     rearGearBody.setNormal(1, rearNormal);
  210.  
  211.     for(int count = 0; count < toothCount; count++) {
  212.         index = 2 + count * 4;
  213.         toothStartAngle
  214.         = gearStartAngle + circularPitchAngle * (double)count;
  215.         toothValleyStartAngle
  216.         = toothStartAngle + toothValleyAngleIncrement;
  217.         nextToothStartAngle = toothStartAngle + circularPitchAngle;
  218.  
  219.         xDirection = (float)Math.cos(toothValleyStartAngle);
  220.         yDirection = (float)Math.sin(toothValleyStartAngle);
  221.         xShaft3 = shaftRadius * xDirection;
  222.         yShaft3 = shaftRadius * yDirection;
  223.         xRoot3 = bodyOuterRadius * xDirection;
  224.         yRoot3 = bodyOuterRadius * yDirection;
  225.  
  226.         xDirection = (float)Math.cos(nextToothStartAngle);
  227.         yDirection = (float)Math.sin(nextToothStartAngle);
  228.         xShaft4 = shaftRadius * xDirection;
  229.         yShaft4 = shaftRadius * yDirection;
  230.         xRoot4 = bodyOuterRadius * xDirection;
  231.         yRoot4 = bodyOuterRadius * yDirection;
  232.  
  233.         coordinate.set(xShaft3, yShaft3, rearZ);
  234.         rearGearBody.setCoordinate(index, coordinate);
  235.         rearGearBody.setNormal(index, rearNormal);
  236.  
  237.         coordinate.set(xRoot3, yRoot3, rearZ);
  238.         rearGearBody.setCoordinate(index + 1, coordinate);
  239.         rearGearBody.setNormal(index + 1, rearNormal);
  240.  
  241.         coordinate.set(xShaft4, yShaft4, rearZ);
  242.         rearGearBody.setCoordinate(index + 2, coordinate);
  243.         rearGearBody.setNormal(index + 2, rearNormal);
  244.  
  245.         coordinate.set(xRoot4, yRoot4, rearZ);
  246.         rearGearBody.setCoordinate(index + 3, coordinate);
  247.         rearGearBody.setNormal(index + 3, rearNormal);
  248.  
  249.     }
  250.     newShape = new Shape3D(rearGearBody, look);
  251.     this.addChild(newShape);
  252.     }
  253.  
  254.     void addCylinderSkins(float shaftRadius, float length,
  255.               int normalDirection, Appearance look) {
  256.     int insideShaftVertexCount;          // #(vertices) for shaft
  257.     int insideShaftStripCount[] = new int[1]; // #(vertices) in strip/strip
  258.     double toothStartAngle, nextToothStartAngle, toothValleyStartAngle;
  259.  
  260.     // A ray from the gear center, used in normal calculations
  261.     float xDirection, yDirection;
  262.  
  263.     // The z coordinates for the body disks
  264.     final float frontZ = -0.5f * length;
  265.     final float rearZ = 0.5f * length;
  266.  
  267.     // Temporary variables for storing coordinates, points, and vectors 
  268.     float xShaft3, yShaft3, xShaft4, yShaft4;
  269.     Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f);
  270.     Vector3f surfaceNormal = new Vector3f();
  271.  
  272.     Shape3D newShape;
  273.     int index;
  274.     int firstIndex;
  275.     int secondIndex;
  276.  
  277.  
  278.     /*
  279.      * Construct gear's inside shaft cylinder
  280.      * First the tooth's up, flat outer, and down distances
  281.      * Second the tooth's flat inner distance
  282.      *
  283.      * Outward facing vertex order:
  284.      *      0_______2____4
  285.      *      |      /|   /|
  286.      *      |    /  |  / |
  287.      *      |  /    | /  |
  288.      *      |/______|/___|
  289.      *      1       3    5
  290.      *
  291.      * Inward facing vertex order:
  292.      *    1_______3____5
  293.      *      |\      |\   |
  294.      *      |  \    | \  |
  295.      *      |    \  |  \ |
  296.      *      |______\|___\|
  297.      *      0       2    4
  298.      */
  299.     insideShaftVertexCount = 4 * toothCount + 2;
  300.     insideShaftStripCount[0] = insideShaftVertexCount;
  301.  
  302.     TriangleStripArray insideShaft
  303.         = new TriangleStripArray(insideShaftVertexCount,
  304.                      GeometryArray.COORDINATES
  305.                      | GeometryArray.NORMALS,
  306.                      insideShaftStripCount);
  307.     xShaft3 = shaftRadius * (float)Math.cos(gearStartAngle);
  308.     yShaft3 = shaftRadius * (float)Math.sin(gearStartAngle);
  309.  
  310.     if (normalDirection == OutwardNormals) {
  311.         surfaceNormal.set(1.0f, 0.0f, 0.0f);
  312.         firstIndex = 1;
  313.         secondIndex = 0;
  314.     } else {
  315.         surfaceNormal.set(-1.0f, 0.0f, 0.0f);
  316.         firstIndex = 0;
  317.         secondIndex = 1;
  318.     }
  319.  
  320.     // Coordinate labeled 0 in the strip
  321.     coordinate.set(shaftRadius, 0.0f, frontZ);
  322.     insideShaft.setCoordinate(firstIndex, coordinate);
  323.     insideShaft.setNormal(firstIndex, surfaceNormal);
  324.  
  325.     // Coordinate labeled 1 in the strip
  326.     coordinate.set(shaftRadius, 0.0f, rearZ);
  327.     insideShaft.setCoordinate(secondIndex, coordinate);
  328.     insideShaft.setNormal(secondIndex, surfaceNormal);
  329.  
  330.     for(int count = 0; count < toothCount; count++) {
  331.         index = 2 + count * 4;
  332.  
  333.         toothStartAngle = circularPitchAngle * (double)count;
  334.         toothValleyStartAngle
  335.         = toothStartAngle + toothValleyAngleIncrement;
  336.         nextToothStartAngle = toothStartAngle + circularPitchAngle;
  337.  
  338.         xDirection = (float)Math.cos(toothValleyStartAngle);
  339.         yDirection = (float)Math.sin(toothValleyStartAngle);
  340.         xShaft3 = shaftRadius * xDirection;
  341.         yShaft3 = shaftRadius * yDirection;
  342.         if (normalDirection == OutwardNormals)
  343.         surfaceNormal.set(xDirection, yDirection, 0.0f);
  344.         else
  345.         surfaceNormal.set(-xDirection, -yDirection, 0.0f);
  346.  
  347.         // Coordinate labeled 2 in the strip
  348.         coordinate.set(xShaft3, yShaft3, frontZ);
  349.         insideShaft.setCoordinate(index + firstIndex, coordinate);
  350.         insideShaft.setNormal(index + firstIndex, surfaceNormal);
  351.  
  352.         // Coordinate labeled 3 in the strip
  353.         coordinate.set(xShaft3, yShaft3, rearZ);
  354.         insideShaft.setCoordinate(index + secondIndex, coordinate);
  355.         insideShaft.setNormal(index + secondIndex, surfaceNormal);
  356.  
  357.         xDirection = (float)Math.cos(nextToothStartAngle);
  358.         yDirection = (float)Math.sin(nextToothStartAngle);
  359.         xShaft4 = shaftRadius * xDirection;
  360.         yShaft4 = shaftRadius * yDirection;
  361.         if (normalDirection == OutwardNormals)
  362.         surfaceNormal.set(xDirection, yDirection, 0.0f);
  363.         else
  364.         surfaceNormal.set(-xDirection, -yDirection, 0.0f);
  365.  
  366.         // Coordinate labeled 4 in the strip
  367.         coordinate.set(xShaft4, yShaft4, frontZ);
  368.         insideShaft.setCoordinate(index + 2 + firstIndex, coordinate);
  369.         insideShaft.setNormal(index + 2 + firstIndex, surfaceNormal);
  370.  
  371.         // Coordinate labeled 5 in the strip
  372.         coordinate.set(xShaft4, yShaft4, rearZ);
  373.         insideShaft.setCoordinate(index + 2 + secondIndex, coordinate);
  374.         insideShaft.setNormal(index + 2 + secondIndex, surfaceNormal);
  375.  
  376.     }
  377.     newShape = new Shape3D(insideShaft, look);
  378.     this.addChild(newShape);
  379.     }
  380.  
  381.     public float getToothTopCenterAngle() {
  382.     return toothTopCenterAngle;
  383.     }
  384.     
  385.     public float getValleyCenterAngle() {
  386.     return valleyCenterAngle;
  387.     }
  388.  
  389.     public float getCircularPitchAngle() {
  390.     return circularPitchAngle;
  391.     }
  392. }
  393.